- 📱 PWA 지원: 홈화면 추가 가능한 Progressive Web App - 🎨 M-Project 색상 스키마: 하늘색, 주황색, 회색, 흰색 일관된 디자인 - 📊 대시보드: 데스크톱 캘린더 뷰 + 모바일 일일 뷰 반응형 디자인 - 📥 분류 센터: Gmail 스타일 받은편지함으로 스마트 분류 시스템 - 🤖 AI 분류 제안: 키워드 기반 자동 분류 제안 및 일괄 처리 - 📷 업로드 모달: 데스크톱(파일 선택) + 모바일(카메라/갤러리) 최적화 - 🏷️ 3가지 분류: Todo(시작일), 캘린더(마감일), 체크리스트(무기한) - 📋 체크리스트: 진행률 표시 및 완료 토글 기능 - 🔄 시놀로지 연동 준비: 메일플러스 연동을 위한 구조 설계 - 📱 반응형 UI: 모든 페이지 모바일 최적화 완료
653 lines
27 KiB
HTML
653 lines
27 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>분류 센터 - 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>
|
|
:root {
|
|
--primary: #3b82f6;
|
|
--primary-dark: #2563eb;
|
|
--success: #10b981;
|
|
--warning: #f59e0b;
|
|
--danger: #ef4444;
|
|
--gray-50: #f9fafb;
|
|
--gray-100: #f3f4f6;
|
|
--gray-200: #e5e7eb;
|
|
--gray-300: #d1d5db;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--gray-50);
|
|
}
|
|
|
|
.btn-primary {
|
|
background-color: var(--primary);
|
|
color: white;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.btn-primary:hover {
|
|
background-color: var(--primary-dark);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
|
|
}
|
|
|
|
/* 분류 카드 스타일 */
|
|
.classify-card {
|
|
background: white;
|
|
border-radius: 1rem;
|
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
|
transition: all 0.3s ease;
|
|
border: 2px solid transparent;
|
|
}
|
|
|
|
.classify-card:hover {
|
|
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.classify-card.selected {
|
|
border-color: var(--primary);
|
|
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.2);
|
|
}
|
|
|
|
/* 분류 버튼 스타일 */
|
|
.classify-btn {
|
|
padding: 12px 24px;
|
|
border-radius: 12px;
|
|
font-weight: 600;
|
|
transition: all 0.2s;
|
|
border: 2px solid transparent;
|
|
}
|
|
|
|
.classify-btn.todo {
|
|
background: linear-gradient(135deg, #dbeafe, #bfdbfe);
|
|
color: #1e40af;
|
|
border-color: #3b82f6;
|
|
}
|
|
|
|
.classify-btn.todo:hover {
|
|
background: linear-gradient(135deg, #bfdbfe, #93c5fd);
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
.classify-btn.calendar {
|
|
background: linear-gradient(135deg, #fef3c7, #fde68a);
|
|
color: #92400e;
|
|
border-color: #f59e0b;
|
|
}
|
|
|
|
.classify-btn.calendar:hover {
|
|
background: linear-gradient(135deg, #fde68a, #fcd34d);
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
.classify-btn.checklist {
|
|
background: linear-gradient(135deg, #d1fae5, #a7f3d0);
|
|
color: #065f46;
|
|
border-color: #10b981;
|
|
}
|
|
|
|
.classify-btn.checklist:hover {
|
|
background: linear-gradient(135deg, #a7f3d0, #6ee7b7);
|
|
transform: scale(1.05);
|
|
}
|
|
|
|
/* 스마트 제안 스타일 */
|
|
.smart-suggestion {
|
|
background: linear-gradient(135deg, #f3e8ff, #e9d5ff);
|
|
border: 2px solid #8b5cf6;
|
|
border-radius: 12px;
|
|
padding: 12px;
|
|
margin: 12px 0;
|
|
}
|
|
|
|
/* 태그 스타일 */
|
|
.tag {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 4px 12px;
|
|
background: #f1f5f9;
|
|
color: #475569;
|
|
border-radius: 20px;
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
margin: 2px;
|
|
cursor: pointer;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.tag:hover {
|
|
background: #e2e8f0;
|
|
}
|
|
|
|
.tag.selected {
|
|
background: var(--primary);
|
|
color: white;
|
|
}
|
|
|
|
/* 애니메이션 */
|
|
.fade-in {
|
|
animation: fadeIn 0.3s ease-in;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; transform: translateY(10px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.slide-up {
|
|
animation: slideUp 0.3s ease-out;
|
|
}
|
|
|
|
@keyframes slideUp {
|
|
from { transform: translateY(20px); opacity: 0; }
|
|
to { transform: translateY(0); opacity: 1; }
|
|
}
|
|
|
|
/* 모바일 최적화 */
|
|
@media (max-width: 768px) {
|
|
.classify-btn {
|
|
padding: 10px 16px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.classify-card {
|
|
margin: 8px 0;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="min-h-screen">
|
|
<!-- 헤더 -->
|
|
<header class="bg-white shadow-sm border-b">
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div class="flex justify-between items-center h-16">
|
|
<div class="flex items-center">
|
|
<button onclick="goBack()" class="mr-4 text-gray-500 hover:text-gray-700">
|
|
<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>
|
|
<span class="ml-3 px-2 py-1 bg-red-100 text-red-800 text-sm rounded-full" id="pendingCount">0</span>
|
|
</div>
|
|
|
|
<div class="flex items-center space-x-4">
|
|
<button onclick="goToDashboard()" class="text-blue-600 hover:text-blue-800 font-medium">
|
|
<i class="fas fa-chart-line mr-1"></i>대시보드
|
|
</button>
|
|
<button onclick="selectAll()" class="text-gray-600 hover:text-gray-800 text-sm">
|
|
<i class="fas fa-check-square mr-1"></i>전체선택
|
|
</button>
|
|
<span class="text-sm text-gray-600" id="currentUser"></span>
|
|
<button onclick="logout()" class="text-gray-500 hover:text-gray-700">
|
|
<i class="fas fa-sign-out-alt"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- 메인 컨텐츠 -->
|
|
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
<!-- 상단 통계 및 필터 -->
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
|
|
<!-- 통계 카드들 -->
|
|
<div class="bg-white rounded-xl shadow-sm p-6">
|
|
<div class="flex items-center">
|
|
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center">
|
|
<i class="fas fa-inbox text-purple-600 text-xl"></i>
|
|
</div>
|
|
<div class="ml-4">
|
|
<p class="text-sm text-gray-600">분류 대기</p>
|
|
<p class="text-2xl font-bold text-gray-900" id="totalPending">0</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-xl shadow-sm p-6">
|
|
<div class="flex items-center">
|
|
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center">
|
|
<i class="fas fa-calendar-day text-blue-600 text-xl"></i>
|
|
</div>
|
|
<div class="ml-4">
|
|
<p class="text-sm text-gray-600">Todo 이동</p>
|
|
<p class="text-2xl font-bold text-gray-900" id="todoMoved">0</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-xl shadow-sm p-6">
|
|
<div class="flex items-center">
|
|
<div class="w-12 h-12 bg-orange-100 rounded-lg flex items-center justify-center">
|
|
<i class="fas fa-calendar-times text-orange-600 text-xl"></i>
|
|
</div>
|
|
<div class="ml-4">
|
|
<p class="text-sm text-gray-600">캘린더 이동</p>
|
|
<p class="text-2xl font-bold text-gray-900" id="calendarMoved">0</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white rounded-xl shadow-sm p-6">
|
|
<div class="flex items-center">
|
|
<div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center">
|
|
<i class="fas fa-check-square text-green-600 text-xl"></i>
|
|
</div>
|
|
<div class="ml-4">
|
|
<p class="text-sm text-gray-600">체크리스트 이동</p>
|
|
<p class="text-2xl font-bold text-gray-900" id="checklistMoved">0</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 필터 및 정렬 -->
|
|
<div class="bg-white rounded-xl shadow-sm p-6 mb-6">
|
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center gap-4">
|
|
<div class="flex flex-wrap gap-2">
|
|
<button onclick="filterItems('all')" class="filter-btn active px-4 py-2 rounded-lg text-sm font-medium">전체</button>
|
|
<button onclick="filterItems('upload')" class="filter-btn px-4 py-2 rounded-lg text-sm font-medium">업로드</button>
|
|
<button onclick="filterItems('mail')" class="filter-btn px-4 py-2 rounded-lg text-sm font-medium">메일</button>
|
|
<button onclick="filterItems('suggested')" class="filter-btn px-4 py-2 rounded-lg text-sm font-medium">제안 있음</button>
|
|
</div>
|
|
|
|
<div class="flex items-center space-x-4">
|
|
<select id="sortBy" class="border border-gray-300 rounded-lg px-3 py-2 text-sm">
|
|
<option value="newest">최신순</option>
|
|
<option value="oldest">오래된순</option>
|
|
<option value="suggested">제안순</option>
|
|
</select>
|
|
|
|
<button onclick="batchClassify()" class="btn-primary px-4 py-2 rounded-lg text-sm" disabled id="batchBtn">
|
|
<i class="fas fa-layer-group mr-1"></i>일괄 분류
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 분류 대기 항목들 -->
|
|
<div class="space-y-4" id="classifyItems">
|
|
<!-- 항목들이 여기에 동적으로 추가됩니다 -->
|
|
</div>
|
|
|
|
<!-- 빈 상태 -->
|
|
<div id="emptyState" class="hidden text-center py-16">
|
|
<i class="fas fa-inbox text-6xl text-gray-300 mb-4"></i>
|
|
<h3 class="text-xl font-semibold text-gray-600 mb-2">분류할 항목이 없습니다</h3>
|
|
<p class="text-gray-500 mb-6">새로운 항목을 업로드하거나 메일을 받으면 여기에 표시됩니다.</p>
|
|
<button onclick="goToDashboard()" class="btn-primary px-6 py-3 rounded-lg">
|
|
<i class="fas fa-plus mr-2"></i>새 항목 추가
|
|
</button>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<!-- JavaScript -->
|
|
<script src="static/js/auth.js"></script>
|
|
<script>
|
|
let pendingItems = [];
|
|
let selectedItems = [];
|
|
let currentFilter = 'all';
|
|
|
|
// 페이지 초기화
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
checkAuthStatus();
|
|
loadPendingItems();
|
|
updateStats();
|
|
});
|
|
|
|
// 분류 대기 항목 로드
|
|
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: ['업무', '미팅', '프로젝트']
|
|
}
|
|
];
|
|
|
|
renderItems();
|
|
}
|
|
|
|
// 항목들 렌더링
|
|
function renderItems() {
|
|
const container = document.getElementById('classifyItems');
|
|
const emptyState = document.getElementById('emptyState');
|
|
|
|
// 필터링
|
|
let filteredItems = pendingItems;
|
|
if (currentFilter !== 'all') {
|
|
filteredItems = pendingItems.filter(item => {
|
|
if (currentFilter === 'suggested') return item.suggested;
|
|
return item.type === currentFilter;
|
|
});
|
|
}
|
|
|
|
if (filteredItems.length === 0) {
|
|
container.innerHTML = '';
|
|
emptyState.classList.remove('hidden');
|
|
return;
|
|
}
|
|
|
|
emptyState.classList.add('hidden');
|
|
|
|
container.innerHTML = filteredItems.map(item => `
|
|
<div class="classify-card p-6 ${selectedItems.includes(item.id) ? 'selected' : ''}" data-id="${item.id}">
|
|
<div class="flex items-start space-x-4">
|
|
<!-- 선택 체크박스 -->
|
|
<div class="flex-shrink-0 mt-1">
|
|
<input type="checkbox" class="w-5 h-5 text-blue-600 rounded"
|
|
${selectedItems.includes(item.id) ? 'checked' : ''}
|
|
onchange="toggleSelection(${item.id})">
|
|
</div>
|
|
|
|
<!-- 타입 아이콘 -->
|
|
<div class="flex-shrink-0">
|
|
<div class="w-12 h-12 rounded-lg flex items-center justify-center ${item.type === 'upload' ? 'bg-blue-100' : 'bg-green-100'}">
|
|
<i class="fas ${item.type === 'upload' ? 'fa-camera text-blue-600' : 'fa-envelope text-green-600'} text-xl"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 사진 (있는 경우) -->
|
|
${item.photo ? `
|
|
<div class="flex-shrink-0">
|
|
<img src="${item.photo}" class="w-20 h-20 object-cover rounded-lg" alt="첨부 사진">
|
|
</div>
|
|
` : ''}
|
|
|
|
<!-- 내용 -->
|
|
<div class="flex-1 min-w-0">
|
|
<h4 class="text-lg font-medium text-gray-900 mb-2">${item.content}</h4>
|
|
|
|
<!-- 메타 정보 -->
|
|
<div class="flex flex-wrap items-center gap-4 text-sm text-gray-500 mb-3">
|
|
<span>
|
|
<i class="fas fa-clock mr-1"></i>${formatDate(item.created_at)}
|
|
</span>
|
|
<span>
|
|
<i class="fas fa-source mr-1"></i>${item.source}
|
|
</span>
|
|
${item.sender ? `
|
|
<span>
|
|
<i class="fas fa-user mr-1"></i>${item.sender}
|
|
</span>
|
|
` : ''}
|
|
</div>
|
|
|
|
<!-- 태그 -->
|
|
<div class="flex flex-wrap gap-1 mb-3">
|
|
${item.tags.map(tag => `<span class="tag">#${tag}</span>`).join('')}
|
|
</div>
|
|
|
|
<!-- 스마트 제안 -->
|
|
${item.suggested ? `
|
|
<div class="smart-suggestion">
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center">
|
|
<i class="fas fa-magic text-purple-600 mr-2"></i>
|
|
<span class="text-sm font-medium text-purple-800">
|
|
AI 제안: <strong>${getSuggestionText(item.suggested)}</strong>
|
|
</span>
|
|
<span class="ml-2 text-xs text-purple-600">(${Math.round(item.confidence * 100)}% 확신)</span>
|
|
</div>
|
|
<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>
|
|
</div>
|
|
</div>
|
|
` : ''}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 분류 버튼들 -->
|
|
<div class="mt-6 flex flex-wrap gap-3 justify-center">
|
|
<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">
|
|
<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">
|
|
<i class="fas fa-check-square mr-2"></i>체크리스트
|
|
<div class="text-xs opacity-75">기한 없음</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
// 애니메이션 적용
|
|
container.querySelectorAll('.classify-card').forEach((card, index) => {
|
|
card.style.animationDelay = `${index * 0.1}s`;
|
|
card.classList.add('fade-in');
|
|
});
|
|
}
|
|
|
|
// 항목 선택 토글
|
|
function toggleSelection(id) {
|
|
const index = selectedItems.indexOf(id);
|
|
if (index > -1) {
|
|
selectedItems.splice(index, 1);
|
|
} else {
|
|
selectedItems.push(id);
|
|
}
|
|
|
|
updateBatchButton();
|
|
renderItems();
|
|
}
|
|
|
|
// 전체 선택
|
|
function selectAll() {
|
|
if (selectedItems.length === pendingItems.length) {
|
|
selectedItems = [];
|
|
} else {
|
|
selectedItems = pendingItems.map(item => item.id);
|
|
}
|
|
|
|
updateBatchButton();
|
|
renderItems();
|
|
}
|
|
|
|
// 일괄 분류 버튼 업데이트
|
|
function updateBatchButton() {
|
|
const batchBtn = document.getElementById('batchBtn');
|
|
if (selectedItems.length > 0) {
|
|
batchBtn.disabled = false;
|
|
batchBtn.textContent = `${selectedItems.length}개 일괄 분류`;
|
|
} else {
|
|
batchBtn.disabled = true;
|
|
batchBtn.innerHTML = '<i class="fas fa-layer-group mr-1"></i>일괄 분류';
|
|
}
|
|
}
|
|
|
|
// 개별 항목 분류
|
|
function classifyItem(id, category) {
|
|
const item = pendingItems.find(item => item.id === id);
|
|
if (!item) return;
|
|
|
|
// 애니메이션 효과
|
|
const card = document.querySelector(`[data-id="${id}"]`);
|
|
card.style.transform = 'scale(0.95)';
|
|
card.style.opacity = '0.7';
|
|
|
|
setTimeout(() => {
|
|
// 항목 제거
|
|
pendingItems = pendingItems.filter(item => item.id !== id);
|
|
selectedItems = selectedItems.filter(itemId => itemId !== id);
|
|
|
|
// UI 업데이트
|
|
renderItems();
|
|
updateStats();
|
|
updateBatchButton();
|
|
|
|
// 성공 메시지
|
|
showToast(`"${item.content}"이(가) ${getSuggestionText(category)}(으)로 이동되었습니다.`, 'success');
|
|
|
|
// TODO: API 호출하여 실제 분류 처리
|
|
console.log(`항목 ${id}을(를) ${category}로 분류`);
|
|
|
|
}, 300);
|
|
}
|
|
|
|
// 제안 수락
|
|
function acceptSuggestion(id, category) {
|
|
classifyItem(id, category);
|
|
}
|
|
|
|
// 일괄 분류
|
|
function batchClassify() {
|
|
if (selectedItems.length === 0) return;
|
|
|
|
// 일괄 분류 모달 또는 드롭다운 표시
|
|
const category = prompt(`선택된 ${selectedItems.length}개 항목을 어디로 분류하시겠습니까?\n1. Todo\n2. 캘린더\n3. 체크리스트\n\n번호를 입력하세요:`);
|
|
|
|
const categories = { '1': 'todo', '2': 'calendar', '3': 'checklist' };
|
|
const selectedCategory = categories[category];
|
|
|
|
if (selectedCategory) {
|
|
selectedItems.forEach(id => {
|
|
setTimeout(() => classifyItem(id, selectedCategory), Math.random() * 500);
|
|
});
|
|
}
|
|
}
|
|
|
|
// 필터링
|
|
function filterItems(filter) {
|
|
currentFilter = filter;
|
|
|
|
// 필터 버튼 활성화 상태 업데이트
|
|
document.querySelectorAll('.filter-btn').forEach(btn => {
|
|
btn.classList.remove('active', 'bg-blue-600', 'text-white');
|
|
btn.classList.add('text-gray-600', 'bg-gray-100');
|
|
});
|
|
|
|
event.target.classList.add('active', 'bg-blue-600', 'text-white');
|
|
event.target.classList.remove('text-gray-600', 'bg-gray-100');
|
|
|
|
renderItems();
|
|
}
|
|
|
|
// 통계 업데이트
|
|
function updateStats() {
|
|
document.getElementById('totalPending').textContent = pendingItems.length;
|
|
document.getElementById('pendingCount').textContent = pendingItems.length;
|
|
|
|
// TODO: 실제 이동된 항목 수 계산
|
|
document.getElementById('todoMoved').textContent = '5';
|
|
document.getElementById('calendarMoved').textContent = '3';
|
|
document.getElementById('checklistMoved').textContent = '7';
|
|
}
|
|
|
|
// 유틸리티 함수들
|
|
function getSuggestionText(category) {
|
|
const texts = {
|
|
'todo': 'Todo',
|
|
'calendar': '캘린더',
|
|
'checklist': '체크리스트'
|
|
};
|
|
return texts[category] || '미분류';
|
|
}
|
|
|
|
function formatDate(dateString) {
|
|
const date = new Date(dateString);
|
|
const now = new Date();
|
|
const diffTime = now - date;
|
|
const diffHours = Math.floor(diffTime / (1000 * 60 * 60));
|
|
|
|
if (diffHours < 1) return '방금 전';
|
|
if (diffHours < 24) return `${diffHours}시간 전`;
|
|
|
|
return date.toLocaleDateString('ko-KR', {
|
|
month: 'short',
|
|
day: 'numeric',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
}
|
|
|
|
function showToast(message, type = 'info') {
|
|
// 간단한 토스트 메시지 (실제로는 더 예쁜 토스트 UI 구현)
|
|
console.log(`[${type.toUpperCase()}] ${message}`);
|
|
|
|
// 임시 알림
|
|
const toast = document.createElement('div');
|
|
toast.className = `fixed top-4 right-4 px-6 py-3 rounded-lg text-white z-50 ${
|
|
type === 'success' ? 'bg-green-500' : 'bg-blue-500'
|
|
}`;
|
|
toast.textContent = message;
|
|
document.body.appendChild(toast);
|
|
|
|
setTimeout(() => {
|
|
toast.remove();
|
|
}, 3000);
|
|
}
|
|
|
|
// 네비게이션 함수들
|
|
function goBack() {
|
|
window.location.href = 'index.html';
|
|
}
|
|
|
|
function goToDashboard() {
|
|
window.location.href = 'dashboard.html';
|
|
}
|
|
|
|
// 전역 함수 등록
|
|
window.toggleSelection = toggleSelection;
|
|
window.selectAll = selectAll;
|
|
window.classifyItem = classifyItem;
|
|
window.acceptSuggestion = acceptSuggestion;
|
|
window.batchClassify = batchClassify;
|
|
window.filterItems = filterItems;
|
|
window.goBack = goBack;
|
|
window.goToDashboard = goToDashboard;
|
|
</script>
|
|
</body>
|
|
</html>
|